(function(){
    'use strict';

    angular.module('zhxAlert', []);
    /**
     * 调度二期报警信息 组件
     * Author: Vicco Wang
     * Date : 2016.08.08
     *
     * 实现目的：
     *
     * 调度二期中实现报警信息的即时展示与交互。
     *
     * PS：该通知可以做为系统公用通知功能使用
     *
     * 主要特点为：
     * 1. 仿MAC OS 的系统消息弹出，在右上角滑动出消息，滑动出消息.
     * 2. 消息可以弹出多个，垂直排列
     * 3. 消息可分为重要消息和一般消息，重要消息系统将不会自动关闭且始终在最顶部
     *
     * 使用方法：
     *
     * 1)模块需要注入 zhxAlert;
     * 2)控制器使用时需要注入 zhxAlertService;
     * 3)控制器中使用方法：
     *
     * zhxAlertService.open(options);
     *
     * 目前可用的options配置项:
     * a. message       [string]    提示的内容
     * b. level         [string]    提示的等级(颜色与是否置顶)，选项为: normal  /   warn   /   danger (设置此选项会置顶)
     * c. showBtn       [boolean]   是否显示按钮
     * d. posDistance   [number]    每个提示的间隔
     * e. frozen        [boolean]   是否置顶，此选项与level设置为'danger'，任意一个启用，都将置顶
     * f. intervalTime  [number]    多少毫秒后关闭该提示.(设置为置顶的消息提示将不会自动关闭)
     * g. processEvent  [function]  『处理』按钮的执行事件，目前接收到的参数为当前消息提示的作用域scope
     * h. detailEvent   [function]  『详情』按钮的执行事件，目前接收到的参数为当前消息提示的作用域scope
     *
     *
     */

    angular.module('zhxAlert').provider('zhxAlert', function(){

        var config = {
            title           : null,
            message         : '提示内容',
            level           : 'normal',         // normal / warn / danger
            showBtn         : true,             // 是否显示按钮部分
            direction       : 'right',          //暂时未实现
            posDistance     : 20,               //每条通知间距
            frozen          : false,            //是否为固定通知，永不消失（需要手动关闭）
            intervalTime    : 6500,            //显示多少ms后自动关闭,
            processEvent    : function(){},     //『处理』按钮事件
            detailEvent     : function(){}      //『详情』按钮事件
        };

        var frozenNum = 0;
        var numIdx = 0;

        this.config = function(cfg){
            //angular.merge support deep copy!
            config = angular.merge({}, config, cfg);
        };

        this.$get = function(){
            return {
                getConfig : function(){
                    return config;
                },
                newId : function(){
                    var date,seed,char,randomChar="",string;
                    date = new Date().getTime();
                    seed = parseInt( Math.random(1,1000) * 1000 );
                    char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
                    for( var i = 0 ; i < 5; i++ ){
                        randomChar += char.charAt(Math.floor(Math.random() * 52));
                    }
                    string = String(seed + date) + randomChar;
                    return 'zhxAlert-' + string.substr(5);
                },
                getFrozenNum : function(){
                    return frozenNum;
                },
                setFrozenNum : function(num){
                    frozenNum = num;
                },
                getIdx : function(){
                    return numIdx;
                },
                setIdx : function(idx){
                    numIdx = idx;
                }

            }
        }
    });


    angular.module("zhxAlert").factory("zhxAlertService", ["$rootScope","$q",'$compile','zhxAlert','$timeout',function($rootScope,$q,$compile,zhxAlert,$timeout){

        var service = {
            /**
             * 创建一个提醒
             * @param opts  用户传入的自定义配置项
             */
            open : function(opts){

                    //创建个新SCOPE
                    var alertScope = $rootScope.$new();
                    //拿到整合好的配置项
                    alertScope.userOptions = angular.extend({}, zhxAlert.getConfig(), opts);

                    if( alertScope.userOptions.frozen || alertScope.userOptions.level == 'danger' ) {
                        //设置为非常重要提醒或固定，都将自动设置此两个属性。非常重要提醒就是固定的
                        alertScope.userOptions.frozen = true;
                        alertScope.userOptions.level = 'danger';

                        var frozenNum = zhxAlert.getFrozenNum();
                        frozenNum++;
                        zhxAlert.setFrozenNum( frozenNum );
                    };

                    var numIdx = zhxAlert.getIdx();
                    numIdx++;
                    zhxAlert.setIdx(numIdx);

                    alertScope.userOptions.numIdx = numIdx;

                    //编译出一个通知出来~
                    var tpl = $compile("<zhx-alert options='userOptions'></zhx-alert>")(alertScope);

                    //扔回DOM树
                    tpl.appendTo('body');

                    //发个通告给大家~
                    $rootScope.$broadcast('zhxAlert.open',{ level : alertScope.userOptions.level } );

            },

            /**
             * 销毁一个提醒
             * @param alertScope    当前被关闭的scope
             * @param status        如果为true,则表示为通过click事件手动进行关闭,自动关闭无需计算位置
             */
            close : function( alertScope, status ){

                alertScope.animateOpacity = 0;
                alertScope.animateRight = -alertScope.style.width / 1.5;
                //当前关闭的如果是固定的，则需要计算总固定数量
                if( alertScope.options.frozen ) {
                    var frozenNum = zhxAlert.getFrozenNum();
                    frozenNum--;
                    zhxAlert.setFrozenNum( frozenNum );
                }
                if( status ){
                    //发个通告给大家~
                    $rootScope.$broadcast('zhxAlert.closedByAction',{ scope : alertScope });
                }

                $timeout(function(){
                    //移除DOM
                    angular.element('#' + alertScope.alertId ).remove();
                    //移除SCOPE
                    alertScope.$parent.$destroy();
                },300)


            }


        };

        return service;

    }]);


    angular.module("zhxAlert").directive("zhxAlert", ["zhxAlert","zhxAlertService","$timeout",function(zhxAlert,zhxAlertService,$timeout){
        return {
            restrict : "E",
            scope : {
                options : '='
            },
            replace : true,
            controller : ["$scope","zhxAlert",function($scope,zhxAlert){

                /**
                 * 目前暂时定义成固定值
                 * @type {{width: number, height: number}}
                 */
                $scope.style = {
                    width   : 300,
                    height  : 70
                };

                $scope.initAnimateTop = function(){
                    if( $scope.frozenNum && $scope.options.frozen ){
                        return -40;
                    } else if ( $scope.frozenNum && !$scope.options.frozen ){
                        return  $scope.frozenNum * ( $scope.style.height + $scope.options.posDistance ) - 40;
                    }
                    return  -40;
                }

                $scope.level = $scope.options.level;
                $scope.frozenNum = zhxAlert.getFrozenNum();

                $scope.alertId          = zhxAlert.newId();
                $scope.animateRight     = -$scope.style.width - 20;
                //$scope.animateOpacity   = 0;
                $scope.animateTop       = $scope.initAnimateTop();
                $scope.interVal         = null;

                $timeout(function(){
                    $scope.animateRight = 20;
                    $scope.animateOpacity = .95;
                },200);


                $scope.closeAlert = function(status){
                    zhxAlertService.close( $scope, status );
                };

                $scope.processAlert = function(){
                    $scope.options.processEvent( $scope );
                };

                $scope.detailAlert = function(){
                    $scope.options.detailEvent( $scope );
                }

                /**
                 * 如果是非固定的，应该在用户设定的延迟事件后自动关闭提醒
                 */
                if( $scope.options.intervalTime && !$scope.options.frozen ){
                    $scope.interVal = $timeout(function(){
                        $scope.closeAlert();
                    },$scope.options.intervalTime);
                }

                /**
                 * 为每一个提醒设置一个接收打开事件，表示当系统新建任意一个提醒时，执行此内容
                 */
                $scope.$on('zhxAlert.open',function(ev,arg){

                    /**
                     * 这里设置当新建任意一个提醒时，当前系统下其他提醒的位置应该进行处理
                     */
                    if( !$scope.frozenNum || !$scope.options.frozen || arg.level == 'danger' ){
                        $scope.animateTop += $scope.style.height + $scope.options.posDistance;
                    }

                });

                /**
                 * 为每一个提醒设置一个接收关闭事件，这里接收的为手动关闭（click）后，应该执行的内容
                 * 其目的主要是为了表示固定与非固定提醒在接收到任意一个提醒关闭后，所在位置应该重新进行计算
                 */
                $scope.$on('zhxAlert.closedByAction',function(ev,arg){

                    /**
                     * arg 为当前关闭对象，arg.scope 为当前关闭对象的scope
                     * 这里判断如果当前关闭的是固定的
                     */
                    if( arg.scope.options.frozen ){
                        //frozen List / danger ...
                        if( $scope.options.frozen ) {
                            if( $scope.options.numIdx < arg.scope.options.numIdx  ) $scope.animateTop -= $scope.style.height + $scope.options.posDistance;
                        //NON frozen List normal / warn ...
                        } else {
                            $scope.animateTop -= $scope.style.height + $scope.options.posDistance;
                        }
                    //关闭的为非固定的
                    } else {
                        if( !$scope.options.frozen && $scope.options.numIdx < arg.scope.options.numIdx  ) $scope.animateTop -= $scope.style.height + $scope.options.posDistance;
                    }

                });

                //设置一个mouseover/leave事件，以清除延迟，保证在鼠标在Alert上时不会消失
                //暂时先不启用此功能
                //$scope.stayInterval = function(status){
                //    if( status ){
                //        $scope.overInterval = $timeout(function(){
                //            if( $scope.interVal !== null ) {
                //                $timeout.cancel( $scope.interVal );
                //                $scope.animateRight = 20;
                //                $scope.animateOpacity = .95;
                //            };
                //        },300);
                //    } else {
                //        if( !$scope.options.frozen ){
                //            $timeout(function(){
                //                $scope.closeAlert();
                //            },$scope.options.intervalTime);
                //        }
                //    }
                //}

            }],
            template :  "<div class='zhx-alert-tip' id='{{ ::alertId }}' ng-mouseover='stayInterval(true)' ng-mouseleave='stayInterval(false)' ng-style='{ width: style.width, height: style.height, top : animateTop ,right : animateRight, opacity: animateOpacity }'>" +
                            "<div class='zhx-alert-level' ng-class='::{ normal: level==\"normal\", warn: level==\"warn\", danger: level==\"danger\" }'>"+
                            "</div>"+
                            "<div class='zhx-alert-content'>"+
                            "{{ ::options.message }}" +
                            "</div>"+
                            "<div class='zhx-alert-btn' ng-if='::options.showBtn'>"+
                                "<ul>" +
                                    "<li ng-click='detailAlert();'>详情</li>" +
                                    "<li ng-if='::options.frozen' ng-click='processAlert();' >处理</li>" +
                                    "<li ng-if='::!options.frozen' ng-click='closeAlert(true);'>关闭</li>" +
                                "</ul>" +
                            "</div>"+
                        "</div>"
        }
    }])


})()
